package com.engine.salary.service.impl;

import com.api.formmode.mybatis.util.SqlProxyHandle;
import com.cloudstore.dev.api.util.Util_DataCache;
import com.engine.common.util.ServiceUtil;
import com.engine.core.impl.Service;
import com.engine.salary.config.SalaryElogConfig;
import com.engine.salary.constant.SalaryDefaultTenantConstant;
import com.engine.salary.entity.datacollection.DataCollectionEmployee;
import com.engine.salary.entity.hrm.DeptInfo;
import com.engine.salary.entity.hrm.HrmStatus;
import com.engine.salary.entity.hrm.PositionInfo;
import com.engine.salary.entity.hrm.SubCompanyInfo;
import com.engine.salary.entity.taxagent.bo.TaxAgentBO;
import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeEmployeeListDTO;
import com.engine.salary.entity.taxagent.dto.TaxAgentManageRangeListDTO;
import com.engine.salary.entity.taxagent.param.*;
import com.engine.salary.entity.taxagent.po.TaxAgentExtRangePO;
import com.engine.salary.entity.taxagent.po.TaxAgentManageRangePO;
import com.engine.salary.entity.taxagent.po.TaxAgentPO;
import com.engine.salary.enums.UserStatusEnum;
import com.engine.salary.enums.datacollection.UseEmployeeTypeEnum;
import com.engine.salary.enums.salarysob.SalaryEmployeeStatusEnum;
import com.engine.salary.enums.salarysob.TargetTypeEnum;
import com.engine.salary.enums.taxagent.TaxAgentRangeTypeEnum;
import com.engine.salary.exception.SalaryRunTimeException;
import com.engine.salary.mapper.sys.SalarySysConfMapper;
import com.engine.salary.mapper.taxagent.TaxAgentExtRangeMapper;
import com.engine.salary.mapper.taxagent.TaxAgentManageRangeMapper;
import com.engine.salary.service.*;
import com.engine.salary.sys.entity.po.SalarySysConfPO;
import com.engine.salary.util.SalaryEntityUtil;
import com.engine.salary.util.SalaryI18nUtil;
import com.engine.salary.util.SalaryLoggerUtil;
import com.engine.salary.util.db.IdGenerator;
import com.engine.salary.util.db.MapperProxyFactory;
import com.engine.salary.util.excel.ExcelParseHelper;
import com.engine.salary.util.page.PageInfo;
import com.engine.salary.util.page.SalaryPageUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.weaver.util.threadPool.ThreadPoolUtil;
import com.weaver.util.threadPool.entity.LocalRunnable;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.Validate;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.BeanUtils;
import weaver.conn.RecordSet;
import weaver.file.ImageFileManager;
import weaver.general.Util;
import weaver.hrm.User;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.stream.Collectors;

/**
 * 个税扣缴义务人的管理范围
 * <p>Copyright: Copyright (c) 2022</p>
 * <p>Company: 泛微软件</p>
 *
 * @author qiantao
 * @version 1.0
 **/
@Slf4j
public class TaxAgentManageRangeServiceImpl extends Service implements TaxAgentManageRangeService {

    private static final ExecutorService taskExecutor = Executors.newFixedThreadPool(5);


    private TaxAgentManageRangeMapper getTaxAgentManageRangeMapper() {
        return MapperProxyFactory.getProxy(TaxAgentManageRangeMapper.class);
    }

    private TaxAgentExtRangeMapper getTaxAgentExtRangeMapper() {
        return MapperProxyFactory.getProxy(TaxAgentExtRangeMapper.class);
    }

    private TaxAgentService getTaxAgentService(User user) {
        return ServiceUtil.getService(TaxAgentServiceImpl.class, user);
    }

    private TaxAgentEmpService getTaxAgentEmpService(User user) {
        return ServiceUtil.getService(TaxAgentEmpServiceImpl.class, user);
    }

    private SalaryArchiveService getSalaryArchiveService(User user) {
        return ServiceUtil.getService(SalaryArchiveServiceImpl.class, user);
    }

    private SalaryEmployeeService getSalaryEmployeeService(User user) {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    private ExtEmpService getExtEmpService(User user) {
        return ServiceUtil.getService(ExtEmpServiceImpl.class, user);
    }


    private SalarySysConfMapper getSalarySysConfMapper() {
        return SqlProxyHandle.getProxy(SalarySysConfMapper.class);
    }

    private SalaryEmployeeService getSalaryEmployeeService() {
        return ServiceUtil.getService(SalaryEmployeeServiceImpl.class, user);
    }

    public SIArchivesService getSIArchivesService(User user) {
        return ServiceUtil.getService(SIArchivesServiceImpl.class, user);
    }

    private List<TaxAgentManageRangePO> listByTaxAgentIds(List<Long> taxAgentIds) {
        if (CollectionUtils.isEmpty(taxAgentIds)) {
            return Lists.newArrayList();
        }
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().rangeType(TaxAgentRangeTypeEnum.TAXAGENT.getValue()).taxAgentIds(taxAgentIds).build());
    }

    @Override
    public List<TaxAgentManageRangePO> listBySubAdminIds(Collection<Long> taxAgentSubAdminIds) {
        if (CollectionUtils.isEmpty(taxAgentSubAdminIds)) {
            return Lists.newArrayList();
        }
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().rangeType(TaxAgentRangeTypeEnum.SUBADMIN.getValue()).taxAgentSubAdminIds(taxAgentSubAdminIds).build());
    }

    /**
     * 获取范围下的人员
     *
     * @param taxAgentId
     * @param allTaxAgentManageRanges
     * @param salaryEmployees
     * @return
     */
    private List<DataCollectionEmployee> getManageRangeSalaryEmployees(Long taxAgentId, List<TaxAgentManageRangePO> allTaxAgentManageRanges, List<DataCollectionEmployee> salaryEmployees) {
        List<TaxAgentManageRangePO> includeAllTaxAgentManageRanges = allTaxAgentManageRanges.stream().filter(f -> f.getIncludeType().equals(NumberUtils.INTEGER_ONE)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(includeAllTaxAgentManageRanges)) {
            return Collections.emptyList();
        }
        List<TaxAgentManageRangePO> excludeAllTaxAgentManageRanges = allTaxAgentManageRanges.stream().filter(f -> f.getIncludeType().equals(NumberUtils.INTEGER_ZERO)).collect(Collectors.toList());

        List<DataCollectionEmployee> includeSalaryEmployees = Lists.newArrayList();
        List<TaxAgentManageRangePO> includeTaxAgentManageRanges = includeAllTaxAgentManageRanges.stream().filter(f -> f.getTaxAgentId().equals(taxAgentId)).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(includeTaxAgentManageRanges)) {
            return includeSalaryEmployees;
        }
        // 根据上一步的查询参数查询人员
        includeSalaryEmployees = listSalaryEmployeeByManageRange(includeTaxAgentManageRanges, salaryEmployees);
        if (CollectionUtils.isEmpty(includeSalaryEmployees)) {
            return includeSalaryEmployees;
        }
        // 查询管理范围（从范围中排除）
        List<TaxAgentManageRangePO> excludeTaxAgentManageRanges = excludeAllTaxAgentManageRanges.stream().filter(f -> f.getTaxAgentId().equals(taxAgentId)).collect(Collectors.toList());
        if (CollectionUtils.isNotEmpty(excludeTaxAgentManageRanges)) {
            // 根据上一步的查询参数查询人员
            List<DataCollectionEmployee> excludeSalaryEmployees = listSalaryEmployeeByManageRange(excludeTaxAgentManageRanges, salaryEmployees);
            // 需要排除的人员范围
            Set<Long> excludeEmployeeIds = SalaryEntityUtil.properties(excludeSalaryEmployees, DataCollectionEmployee::getEmployeeId);
            // 过滤人员
            includeSalaryEmployees = includeSalaryEmployees.stream().filter(salaryEmployee -> !excludeEmployeeIds.contains(salaryEmployee.getEmployeeId())).collect(Collectors.toList());
        }
        return includeSalaryEmployees;
    }

    /**
     * 根据范围加载人员
     *
     * @param taxAgentManageRanges
     * @return
     */
    private List<DataCollectionEmployee> listSalaryEmployeeByManageRange(List<TaxAgentManageRangePO> taxAgentManageRanges, List<DataCollectionEmployee> salaryEmployees) {
        if (CollectionUtils.isEmpty(taxAgentManageRanges) || CollectionUtils.isEmpty(salaryEmployees)) {
            return Collections.emptyList();
        }
        // 获取虚拟部门下人员信息
        List<Long> virtualDepartmentIds = taxAgentManageRanges.stream().filter(manageRange -> manageRange.getTargetType().equals(TargetTypeEnum.DEPT.getValue()) && manageRange.getTargetId().compareTo(0L) < 0).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
        List<DataCollectionEmployee> virtualEmpListByDep = getSalaryEmployeeService(user).getVirtualEmpByVirtualDepIds(virtualDepartmentIds);
        Map<Long, Set<Long>> virtualDepMap = SalaryEntityUtil.group2Map(virtualEmpListByDep, DataCollectionEmployee::getDepartmentId, DataCollectionEmployee::getEmployeeId);

        // 获取虚拟分部下人员信息
        List<Long> virtualSubCompanyIds = taxAgentManageRanges.stream().filter(manageRange -> manageRange.getTargetType().equals(TargetTypeEnum.SUBCOMPANY.getValue()) && manageRange.getTargetId().compareTo(0L) < 0).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
        List<DataCollectionEmployee> virtualEmpListBySubCom = getSalaryEmployeeService(user).getVirtualEmpByVirtualSubCompanyIds(virtualSubCompanyIds);
        Map<Long, Set<Long>> virtualSubCompanyMap = SalaryEntityUtil.group2Map(virtualEmpListBySubCom, DataCollectionEmployee::getSubcompanyid, DataCollectionEmployee::getEmployeeId);

        List<DataCollectionEmployee> salaryEmployeeList = Lists.newArrayList();
        for (TaxAgentManageRangePO manageRange : taxAgentManageRanges) {
            if (!TargetTypeEnum.SQL.getValue().equals(manageRange.getTargetType())) {
                boolean isVirtual = manageRange.getTargetId().compareTo(0L) < 0 ? true : false;
                List<DataCollectionEmployee> employees = salaryEmployees.stream().filter(salaryEmployee -> {
                    if (StringUtils.isEmpty(manageRange.getEmployeeStatus()) || !manageRange.getEmployeeStatus().contains("\"" + salaryEmployee.getStatus() + "\"")) {
                        return false;
                    }
                    if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.ALL.getValue())) {
                        return true;
                    }
                    if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.EMPLOYEE.getValue()) && Objects.equals(manageRange.getTargetId(), salaryEmployee.getEmployeeId())) {
                        return true;
                    }
                    if (isVirtual) {
                        if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.DEPT.getValue())) {
                            Set<Long> empIds = virtualDepMap.get(manageRange.getTargetId());
                            if (CollectionUtils.isNotEmpty(empIds) && empIds.contains(salaryEmployee.getEmployeeId())) {
                                return true;
                            }
                        }
                        if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.SUBCOMPANY.getValue())) {
                            Set<Long> empIds = virtualSubCompanyMap.get(manageRange.getTargetId());
                            if (CollectionUtils.isNotEmpty(empIds) && empIds.contains(salaryEmployee.getEmployeeId())) {
                                return true;
                            }
                        }
                    } else {
                        if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.DEPT.getValue()) && Objects.equals(manageRange.getTargetId(), salaryEmployee.getDepartmentId())) {
                            return true;
                        }
                        if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.SUBCOMPANY.getValue()) && Objects.equals(manageRange.getTargetId(), salaryEmployee.getSubcompanyid())) {
                            return true;
                        }
                    }
                    if (Objects.equals(manageRange.getTargetType(), TargetTypeEnum.POSITION.getValue()) && Objects.equals(manageRange.getTargetId(), salaryEmployee.getJobtitleId())) {
                        return true;
                    }
                    return false;
                }).collect(Collectors.toList());
                salaryEmployeeList.addAll(employees);
            }
        }

        for (TaxAgentManageRangePO manageRange : taxAgentManageRanges) {
            if (TargetTypeEnum.SQL.getValue().equals(manageRange.getTargetType())) {
                String sql = manageRange.getTarget();
                List<Long> empIds = new ArrayList<>();
                RecordSet rs = new RecordSet();
                if (rs.execute(sql)) {
                    while (rs.next()) {
                        empIds.add((long) rs.getInt("id"));
                    }
                }
                List<DataCollectionEmployee> employees = getSalaryEmployeeService(user).getEmployeeByIds(empIds);
                if (StringUtils.isNotBlank(manageRange.getEmployeeStatus())) {
                    employees = employees.stream().filter(salaryEmployee -> manageRange.getEmployeeStatus().contains("\"" + salaryEmployee.getStatus() + "\"")).collect(Collectors.toList());
                }
                salaryEmployeeList.addAll(employees);
            }
        }

        // 去重
        salaryEmployeeList = salaryEmployeeList.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(DataCollectionEmployee::getEmployeeId))), ArrayList::new));
        return salaryEmployeeList;
    }

    /**
     * 根据分管理员id获取管理范围列表
     *
     * @param subAdminId
     * @param includeType
     * @return
     */
    private List<TaxAgentManageRangePO> listBySubAdminIdAndIncludeType(Long subAdminId, Integer includeType) {
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentSubAdminId(subAdminId).rangeType(TaxAgentRangeTypeEnum.SUBADMIN.getValue()).includeType(includeType).build());
    }

    /**
     * 获取个税口角义务人的管理范围
     *
     * @param taxAgentId
     * @param includeType
     * @return
     */
    @Override
    public List<TaxAgentManageRangePO> listByTaxAgentIdAndIncludeType(Long taxAgentId, Integer includeType) {
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentId(taxAgentId).rangeType(TaxAgentRangeTypeEnum.TAXAGENT.getValue()).includeType(includeType).build());
    }

    @Override
    public PageInfo<TaxAgentManageRangeListDTO> listPageByParamAndIncludeType(TaxAgentSubAdminRangeQueryParam queryParam, Integer includeType) {
        // 查询已有的管理范围
        List<TaxAgentManageRangePO> taxAgentManageRanges = listBySubAdminIdAndIncludeType(queryParam.getSubAdminId(), includeType);
        return listPageByParamAndIncludeType(taxAgentManageRanges, queryParam, includeType);
    }

    @Override
    public PageInfo<TaxAgentManageRangeListDTO> listPageByParamAndIncludeType(TaxAgentRangeQueryParam queryParam, Integer includeType) {
        // 查询已有的管理范围
        List<TaxAgentManageRangePO> taxAgentManageRanges = listByTaxAgentIdAndIncludeType(queryParam.getTaxAgentId(), includeType);
        return listPageByParamAndIncludeType(taxAgentManageRanges, queryParam, includeType);
    }

    private PageInfo<TaxAgentManageRangeListDTO> listPageByParamAndIncludeType(List<TaxAgentManageRangePO> taxAgentManageRanges, TaxAgentManageRangeQueryParam queryParam, Integer includeType) {

        // 查询人员信息
        List<Long> employeeIds = taxAgentManageRanges.stream().filter(e -> Objects.equals(e.getTargetType(), TargetTypeEnum.EMPLOYEE.getValue())).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
//        List<DataCollectionEmployee> employeeComInfos = comInfoCache.getCacheList(HrmEmployeeComInfo.class, employeeIds);
        List<DataCollectionEmployee> employeeComInfos = getSalaryEmployeeService().getEmployeeByIdsAll(employeeIds);
        // 查询部门信息
        List<Long> departmentIds = taxAgentManageRanges.stream().filter(e -> Objects.equals(e.getTargetType(), TargetTypeEnum.DEPT.getValue())).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
        List<DeptInfo> departmentComInfos = getSalaryEmployeeService().getDeptInfoList(departmentIds);
        // 虚拟部门
        List<Long> virtualDepIds = departmentIds.stream().filter(id -> id.compareTo(0L) < 0).collect(Collectors.toList());
        departmentComInfos.addAll(getSalaryEmployeeService().getVirtualDeptInfoList(virtualDepIds));

        // 查询分部信息
        List<Long> subDepartmentIds = taxAgentManageRanges.stream().filter(e -> Objects.equals(e.getTargetType(), TargetTypeEnum.SUBCOMPANY.getValue())).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
        List<SubCompanyInfo> subDepartmentComInfos = getSalaryEmployeeService().getSubCompanyInfoList(subDepartmentIds);
        // 虚拟分部
        List<Long> virtualSubCompanyIds = subDepartmentIds.stream().filter(id -> id.compareTo(0L) < 0).collect(Collectors.toList());
        subDepartmentComInfos.addAll(getSalaryEmployeeService().getVirtualSubCompanyInfoList(virtualSubCompanyIds));

        // 查询岗位信息
        List<Long> positionIds = taxAgentManageRanges.stream().filter(e -> Objects.equals(e.getTargetType(), TargetTypeEnum.POSITION.getValue())).map(TaxAgentManageRangePO::getTargetId).collect(Collectors.toList());
        List<PositionInfo> positionComInfos = getSalaryEmployeeService().listPositionInfo(positionIds);
        // 分页参数
        PageInfo<TaxAgentManageRangeListDTO> dtoPage = SalaryPageUtil.buildPage(queryParam.getCurrent(), queryParam.getPageSize(), TaxAgentManageRangeListDTO.class);
        // 查询人员状态
//        List<HrmStatus> hrmStatusList = hrmCommonHrmStatusService.list();
        List<HrmStatus> hrmStatusList = UserStatusEnum.getHrmStatusList();
        // 薪资账套的人员范围po转换成列表dto
        List<TaxAgentManageRangeListDTO> taxAgentManageRangeList = TaxAgentBO.convert2ListDTO(taxAgentManageRanges, employeeComInfos, departmentComInfos, subDepartmentComInfos, positionComInfos, hrmStatusList);
        // 根据对象名称过滤
        if (StringUtils.isNotEmpty(queryParam.getTargetName())) {
            taxAgentManageRangeList = taxAgentManageRangeList.stream().filter(f -> f.getTargetName().contains(queryParam.getTargetName())).collect(Collectors.toList());
        }
        // 填充总数和当页数据
        dtoPage.setTotal(taxAgentManageRangeList.size());
        dtoPage.setList(SalaryPageUtil.subList(dtoPage.getPageNum(), dtoPage.getPageSize(), taxAgentManageRangeList));
        return dtoPage;
    }

    /**
     * 根据个税口角义务人id保存管理范围
     *
     * @param saveParam 保存参数
     */
    @Override
    public void save(TaxAgentRangeSaveParam saveParam) {

        checkParam(saveParam);

        // 查询个税扣缴义务人
        TaxAgentPO taxAgent = getTaxAgentService(user).getById(saveParam.getTaxAgentId());
        if (Objects.isNull(taxAgent)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(108605, "参数错误，个税扣缴义务人不存在或不在权限范围内"));
        }
        // 查询已有的管理范围
        List<TaxAgentManageRangePO> taxAgentManageAllRanges = listByTaxAgentId(saveParam.getTaxAgentId());

        List<TaxAgentManageRangePO> taxAgentManageRanges = taxAgentManageAllRanges.stream().filter(f -> f.getIncludeType().equals(saveParam.getIncludeType())).collect(Collectors.toList());
        List<TaxAgentManageRangePO> oldManageList = new ArrayList<>();
        taxAgentManageRanges.stream().forEach(p -> {
            TaxAgentManageRangePO target = new TaxAgentManageRangePO();
            BeanUtils.copyProperties(p, target);
            oldManageList.add(target);
        });
        // 处理一下本次的保存参数（如果原来添加过对应的人员（/部门/岗位），那么本次不需要新增，只需要更新）
        TaxAgentBO.Result result = TaxAgentBO.handleTaxAgentRange(taxAgentManageRanges, saveParam, taxAgent.getId(), (long) user.getUID(), false);

        /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================start */
        List<TaxAgentManageRangePO> allRanges = Lists.newArrayList(taxAgentManageAllRanges);
        allRanges.addAll(result.getNeedInsertTaxAgentManageRanges());
        allRanges.addAll(result.getNeedUpdateTaxAgentManageRanges());
        // 去重
        allRanges = allRanges.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getTaxAgentId() + "." + f.getRangeType() + "." + f.getTargetType() + "." + f.getTargetId() + "." + f.getEmployeeStatus() + "." + f.getIncludeType()))), ArrayList::new));

        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService().listAll(UseEmployeeTypeEnum.ALL);
        List<DataCollectionEmployee> allSalaryEmployees = this.getManageRangeSalaryEmployees(saveParam.getTaxAgentId(), allRanges, salaryEmployees);

        /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================end */
        if (CollectionUtils.isNotEmpty(result.getNeedInsertTaxAgentManageRanges())) {
            result.getNeedInsertTaxAgentManageRanges().forEach(range -> {
                getTaxAgentManageRangeMapper().insertIgnoreNull(range);
                // 记录操作日志
                String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                SalaryLoggerUtil.recordAddSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "新增人员范围"), SalaryI18nUtil.getI18nLabel(0, "新增人员范围") + name, range, user);
            });

        }
        if (CollectionUtils.isNotEmpty(result.getNeedUpdateTaxAgentManageRanges())) {
            Map<Long, TaxAgentManageRangePO> oldMap = SalaryEntityUtil.convert2Map(oldManageList, TaxAgentManageRangePO::getId);
            result.getNeedUpdateTaxAgentManageRanges().forEach(range -> {
                getTaxAgentManageRangeMapper().updateIgnoreNull(range);
                // 记录操作日志
                TaxAgentManageRangePO oldPO = oldMap.getOrDefault(range.getId(), TaxAgentManageRangePO.builder().build());
                String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                SalaryLoggerUtil.recordUpdateSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "更新人员范围"), SalaryI18nUtil.getI18nLabel(0, "更新人员范围") + name, oldPO, range, user);
            });

        }

        /* 同步本地人员范围的关联人员=========================== */
        syncLocalEmp(saveParam.getTaxAgentId(), allSalaryEmployees, saveParam.isSync());

    }

    private void checkParam(TaxAgentRangeSaveParam saveParam) {
        if (saveParam == null) {
            throw new SalaryRunTimeException("参数错误");
        }

        if (Objects.isNull(saveParam.getTaxAgentId())) {
            throw new SalaryRunTimeException("个税扣缴义务人的id不允许为空");
        }

        if (saveParam.getIncludeType() != 0 && saveParam.getIncludeType() != 1) {
            throw new SalaryRunTimeException("只能选择 关联人员范围/从范围中排除");
        }

        if (CollectionUtils.isEmpty(saveParam.getEmployeeStatus())) {
            throw new SalaryRunTimeException("员工状态不允许为空");
        }

        if (CollectionUtils.isNotEmpty(saveParam.getTargetParams())) {
            saveParam.getTargetParams().forEach(target -> {
                if (target.getTargetType() == null) {
                    throw new SalaryRunTimeException("对象类型不能为空");
                }
                if (target.getTargetType() == TargetTypeEnum.SQL) {
                    if (target.getTarget() == null) {
                        throw new SalaryRunTimeException("sql不能为空");
                    }
                    target.setTargetId(0L);
                } else {
                    if (target.getTargetId() == null) {
                        throw new SalaryRunTimeException("对象不能为空");
                    }
                }
            });
        }
    }

    @Override
    public void edit(TaxAgentRangeSaveParam param) {
        checkParam(param);

        if (param.getId() == null) {
            throw new SalaryRunTimeException("id不能为空");
        }

        // 查询个税扣缴义务人
        TaxAgentPO taxAgent = getTaxAgentService(user).getById(param.getTaxAgentId());
        if (Objects.isNull(taxAgent)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(108605, "参数错误，个税扣缴义务人不存在或不在权限范围内"));
        }

        //删除原有的管理范围
        getTaxAgentManageRangeMapper().deleteByIds(Collections.singleton(param.getId()));

        // 查询已有的管理范围
        List<TaxAgentManageRangePO> taxAgentManageAllRanges = listByTaxAgentId(param.getTaxAgentId());

        List<TaxAgentManageRangePO> taxAgentManageRanges = taxAgentManageAllRanges.stream().filter(f -> f.getIncludeType().equals(param.getIncludeType())).collect(Collectors.toList());
        List<TaxAgentManageRangePO> oldManageList = new ArrayList<>();
        taxAgentManageRanges.stream().forEach(p -> {
            TaxAgentManageRangePO target = new TaxAgentManageRangePO();
            BeanUtils.copyProperties(p, target);
            oldManageList.add(target);
        });
        // 处理一下本次的保存参数（如果原来添加过对应的人员（/部门/岗位），那么本次不需要新增，只需要更新）
        TaxAgentBO.Result result = TaxAgentBO.handleTaxAgentRange(taxAgentManageRanges, param, taxAgent.getId(), (long) user.getUID(), false);

        /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================start */
        List<TaxAgentManageRangePO> allRanges = Lists.newArrayList(taxAgentManageAllRanges);
        allRanges.addAll(result.getNeedInsertTaxAgentManageRanges());
        allRanges.addAll(result.getNeedUpdateTaxAgentManageRanges());
        // 去重
        allRanges = allRanges.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getTaxAgentId() + "." + f.getRangeType() + "." + f.getTargetType() + "." + f.getTargetId() + "." + f.getEmployeeStatus() + "." + f.getIncludeType()))), ArrayList::new));

        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService().listAll(UseEmployeeTypeEnum.ALL);
        List<DataCollectionEmployee> allSalaryEmployees = this.getManageRangeSalaryEmployees(param.getTaxAgentId(), allRanges, salaryEmployees);

        /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================end */
        if (CollectionUtils.isNotEmpty(result.getNeedInsertTaxAgentManageRanges())) {
            result.getNeedInsertTaxAgentManageRanges().forEach(range -> {
                getTaxAgentManageRangeMapper().insertIgnoreNull(range);
                // 记录操作日志
                String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                SalaryLoggerUtil.recordAddSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "新增人员范围"), SalaryI18nUtil.getI18nLabel(0, "新增人员范围") + name, range, user);
            });

        }
        if (CollectionUtils.isNotEmpty(result.getNeedUpdateTaxAgentManageRanges())) {
            Map<Long, TaxAgentManageRangePO> oldMap = SalaryEntityUtil.convert2Map(oldManageList, TaxAgentManageRangePO::getId);
            result.getNeedUpdateTaxAgentManageRanges().forEach(range -> {
                getTaxAgentManageRangeMapper().updateIgnoreNull(range);
                // 记录操作日志
                TaxAgentManageRangePO oldPO = oldMap.getOrDefault(range.getId(), TaxAgentManageRangePO.builder().build());
                String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                SalaryLoggerUtil.recordUpdateSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "更新人员范围"), SalaryI18nUtil.getI18nLabel(0, "更新人员范围") + name, oldPO, range, user);
            });

        }

        /* 同步本地人员范围的关联人员=========================== */
        syncLocalEmp(param.getTaxAgentId(), allSalaryEmployees, param.isSync());
    }

    private void syncLocalEmp(Long taxAgentId, List<DataCollectionEmployee> allSalaryEmployees, boolean isSync) {
        if (isSync) {
            syncLocalEmpRange(taxAgentId, allSalaryEmployees, (long) user.getUID());
            //生成档案
            generateArchive();
        } else {
            taskExecutor.execute(() -> {
                syncLocalEmpRange(taxAgentId, allSalaryEmployees, (long) user.getUID());
                //生成档案
                generateArchive();
            });
        }

    }

    /**
     * 生成档案
     */
    private void generateArchive() {
        //生成薪资档案
        String salaryArchiveChangeSign = (String) Util_DataCache.getObjVal("salaryArchiveChangeSign");
        if (salaryArchiveChangeSign == null || "0".equals(salaryArchiveChangeSign)) {
            try {
                //开始同步中....
                Util_DataCache.setObjVal("salaryArchiveChangeSign", "1");
                getSalaryArchiveService(user).handleChangeData(1L);
            } finally {
                //同步结束....
                Util_DataCache.setObjVal("salaryArchiveChangeSign", "0");
            }

        }
        //生成社保福利档案
        String welSign = (String) Util_DataCache.getObjVal("welfareChangeSign");
        if (welSign == null || "0".equals(welSign)) {
            getSIArchivesService(user).handleChangeData(1L);
        }
    }


    /**
     * 根据个税口角义务人id保存管理范围
     *
     * @param saveParam 保存参数
     */
    @Override
    public void saveExtRange(TaxAgentManageRangeExtSaveParam saveParam) {

        if (saveParam == null) {
            throw new SalaryRunTimeException("参数错误");
        }
        Long taxAgentId = saveParam.getTaxAgentId();
        if (Objects.isNull(taxAgentId)) {
            throw new SalaryRunTimeException("个税扣缴义务人的id不允许为空");
        }


        // 查询个税扣缴义务人
        TaxAgentPO taxAgent = getTaxAgentService(user).getById(taxAgentId);
        if (Objects.isNull(taxAgent)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(108605, "参数错误，个税扣缴义务人不存在或不在权限范围内"));
        }

        List<Long> targetIds = saveParam.getTargetIds();
        List<DataCollectionEmployee> employees = getExtEmpService(user).getEmployeeByIds(targetIds);
        if (Objects.isNull(employees)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(108605, "参数错误，无此外部人员"));
        }

        Date now = new Date();
        List<TaxAgentExtRangePO> oldPO = listAllExtBytaxAgentId(taxAgentId);
        List<Long> oldIds = SalaryEntityUtil.properties(oldPO, TaxAgentExtRangePO::getTargetId, Collectors.toList());
        targetIds.stream().filter(targetId -> !oldIds.contains(targetId)).forEach(targetId -> {
            TaxAgentExtRangePO po = TaxAgentExtRangePO.builder().id(IdGenerator.generate()).taxAgentId(taxAgentId).targetId(targetId).creator((long) user.getUID()).createTime(now).updateTime(now).deleteType(0).targetType(1).tenantKey(SalaryDefaultTenantConstant.DEFAULT_TENANT_KEY).build();

            getTaxAgentExtRangeMapper().insertIgnoreNull(po);
            // 记录日志
            String name = taxAgent.getName() + "_" + saveParam.getTaxAgentId();
            SalaryLoggerUtil.recordAddSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, taxAgent.getId(), name, SalaryI18nUtil.getI18nLabel(0, "新增非系统人员范围"), SalaryI18nUtil.getI18nLabel(0, "新增非系统人员范围") + name, po, user);
        });
        List<DataCollectionEmployee> oldEmpList = getExtEmpService(user).getEmployeeByIds(oldIds);
        employees.addAll(oldEmpList);
        // 去重
        employees = employees.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(e -> e.getEmployeeId()))), ArrayList::new));


        /* 同步本地人员范围的关联人员=========================== */
        if (saveParam.isSync()) {
            //同步执行
            syncLocalExtEmp(taxAgentId, employees);
        } else {
            List<DataCollectionEmployee> finalEmployees = employees;
            taskExecutor.execute(() -> {
                syncLocalExtEmp(taxAgentId, finalEmployees);
            });
        }

    }

    private List<TaxAgentExtRangePO> listAllExtBytaxAgentId(Long taxAgentId) {
        if (taxAgentId == null) {
            return new ArrayList<>();
        }
        return getTaxAgentExtRangeMapper().listSome(TaxAgentExtRangePO.builder().taxAgentId(taxAgentId).build());
    }

    private List<TaxAgentExtRangePO> listExtByIds(Collection<Long> targetIds) {
        if (CollectionUtils.isEmpty(targetIds)) {
            return new ArrayList<>();
        }
        return getTaxAgentExtRangeMapper().listSome(TaxAgentExtRangePO.builder().ids(targetIds).build());
    }

    @Override
    public void deleteExtRange(Collection<Long> ids) {
        // 查询管理范围
        List<TaxAgentExtRangePO> taxAgentManageRanges = listExtByIds(ids);
        if (CollectionUtils.isEmpty(taxAgentManageRanges)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98604, "数据不存在或已被删除"));
        }
        List<Long> taxAgentIds = taxAgentManageRanges.stream().map(TaxAgentExtRangePO::getTaxAgentId).distinct().collect(Collectors.toList());
        if (taxAgentIds.size() > 1) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110159, "一次只能删一个个税个税扣缴义务人的范围"));
        }
        // 删除管理范围
        getTaxAgentExtRangeMapper().deleteByIds(ids);
        // 记录日志
        SalaryLoggerUtil.recordDeleteSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, taxAgentManageRanges.get(0).getTaxAgentId(), ids.toString(), SalaryI18nUtil.getI18nLabel(0, "删除非系统人员范围"), SalaryI18nUtil.getI18nLabel(0, "删除非系统人员范围") + ids.toString(), null, user);
    }

    private void syncLocalExtEmp(Long taxAgentId, List<DataCollectionEmployee> allSalaryEmployees) {

        List<TaxAgentEmpSaveParam> taxAgentEmpSaveParamList = Collections.singletonList(getTaxAgentEmpSyncParam(taxAgentId, allSalaryEmployees));
        // 同步个税扣缴义务人的人员
        getTaxAgentEmpService(user).syncTaxAgentExtEmployee(taxAgentEmpSaveParamList, (long) user.getUID());

//        //生成档案
        getSalaryArchiveService(user).handleChangeData(1L);
//        //生成社保福利档案
        String welSign = (String) Util_DataCache.getObjVal("welfareChangeSign");
        if (welSign == null || "0".equals(welSign)) {
            getSIArchivesService(user).handleChangeData(1L);
        }
    }


    /**
     * 获取个税口角义务人的管理范围
     *
     * @param taxAgentId
     * @return
     */
    private List<TaxAgentManageRangePO> listByTaxAgentId(Long taxAgentId) {
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentId(taxAgentId).rangeType(TaxAgentRangeTypeEnum.TAXAGENT.getValue()).build());
    }

    private List<TaxAgentManageRangePO> listSunAdminRangeByTaxAgentId(Long taxAgentId) {
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentId(taxAgentId).rangeType(TaxAgentRangeTypeEnum.SUBADMIN.getValue()).build());
    }


    /**
     * 根据分管理员id获取管理范围列表
     *
     * @param subAdminId
     * @return
     */
    private List<TaxAgentManageRangePO> listBySubAdminId(Long subAdminId) {
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentSubAdminId(subAdminId).rangeType(TaxAgentRangeTypeEnum.SUBADMIN.getValue()).build());
    }

    private List<TaxAgentManageRangePO> listByIds(Collection<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return Collections.emptyList();
        }
        return getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().ids(ids).build());
    }

    @Override
    public void deleteByIds(Collection<Long> ids) {
        // 查询管理范围
        List<TaxAgentManageRangePO> taxAgentManageRangeList = listByIds(ids);

        if (CollectionUtils.isEmpty(taxAgentManageRangeList)) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(98604, "数据不存在或已被删除"));
        }
        List<Long> taxAgentIds = taxAgentManageRangeList.stream().map(TaxAgentManageRangePO::getTaxAgentId).distinct().collect(Collectors.toList());
        if (taxAgentIds.size() > 1) {
            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110159, "一次只能删一个个税个税扣缴义务人的范围"));
        }
        List<TaxAgentManageRangePO> taxAgentManageRanges = this.listByTaxAgentIds(taxAgentIds);
        List<TaxAgentManageRangePO> allManageRanges = taxAgentManageRanges.stream().filter(f -> !ids.contains(f.getId())).collect(Collectors.toList());
        List<TaxAgentManageRangePO> allRanges = allManageRanges.stream().filter(f -> f.getRangeType().equals(TaxAgentRangeTypeEnum.TAXAGENT.getValue())).collect(Collectors.toList());
//        List<TaxAgentManageRangePO> allSubAdminRanges = allManageRanges.stream().filter(f -> f.getRangeType().equals(TaxAgentRangeTypeEnum.SUBADMIN.getValue())).collect(Collectors.toList());
        Long taxAgentId = taxAgentIds.get(0);
        TaxAgentPO taxAgentPO = getTaxAgentService(user).getById(taxAgentId);

        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService(user).listAll(UseEmployeeTypeEnum.ORG);
        List<DataCollectionEmployee> allSalaryEmployees = this.getManageRangeSalaryEmployees(taxAgentId, allRanges, salaryEmployees);

//        List<DataCollectionEmployee> allSubAdminSalaryEmployees = this.getManageRangeSalaryEmployees(taxAgentId, allSubAdminRanges, salaryEmployees);
//        allSalaryEmployees.forEach(f -> {
//            allSubAdminSalaryEmployees.removeIf(a -> a.getEmployeeId().equals(f.getEmployeeId()));
//        });
//        if (CollectionUtils.isNotEmpty(allSubAdminSalaryEmployees)) {
//            throw new SalaryRunTimeException(SalaryI18nUtil.getI18nLabel(110160, "分管理员存在超出整体人员范围以外的人员，不可删除"));
//        }
        // 删除管理范围
        getTaxAgentManageRangeMapper().deleteByIds(ids);

        // 记录操作日志
        taxAgentManageRangeList.stream().forEach(range -> {
            String name = taxAgentPO.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
            SalaryLoggerUtil.recordDeleteSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "删除人员范围"), SalaryI18nUtil.getI18nLabel(0, "删除人员范围") + name, range, user);
        });


        /** 同步本地人员范围的关联人员=========================== */
        syncLocalEmp(taxAgentId, allSalaryEmployees, false);
    }

    @Override
    public PageInfo<TaxAgentExtRangePO> listExt(TaxAgentRangeExtQueryParam param) {
        if (param.getTaxAgentId() == null) {
            throw new SalaryRunTimeException("扣缴义务人id为空");
        }

        List<TaxAgentExtRangePO> taxAgentExtRangePOS = getTaxAgentExtRangeMapper().list(TaxAgentExtRangePO.builder().taxAgentId(param.getTaxAgentId()).build());
        if (StringUtils.isNotBlank(param.getTargetName())) {
            taxAgentExtRangePOS = taxAgentExtRangePOS.stream().filter(po -> po.getTargetName().contains(param.getTargetName())).collect(Collectors.toList());
        }
        return SalaryPageUtil.buildPage(param.getCurrent(), param.getPageSize(), taxAgentExtRangePOS, TaxAgentExtRangePO.class);
    }

    @Override
    public void deleteByTaxAgentIds(Collection<Long> taxAgentIds) {
        getTaxAgentManageRangeMapper().deleteByTaxAgentIds(taxAgentIds);
        // 删除管理范围下的所有人员
        getTaxAgentEmpService(user).deleteByTaxAgentIds(taxAgentIds);
    }


    /**
     * 同步处理所有人员范围
     *
     * @param taxAgentIds 为空代表所有个税扣缴义务人
     */
    private void handleSyncTaxAgentEmpData(List<Long> taxAgentIds) {

        List<TaxAgentManageRangePO> allManageRanges = getTaxAgentManageRangeMapper().listSome(TaxAgentManageRangePO.builder().taxAgentIds(taxAgentIds).build());

        if (CollectionUtils.isEmpty(allManageRanges)) {
            return;
        }
        taxAgentIds = allManageRanges.stream().map(TaxAgentManageRangePO::getTaxAgentId).distinct().collect(Collectors.toList());
        // 获取所有人员
        List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService(user).listAll(UseEmployeeTypeEnum.ORG);

        List<TaxAgentEmpSaveParam> taxAgentEmpSaveParamList = Lists.newArrayList();
        List<TaxAgentSubAdminEmpSaveParam> subAdminEmpSaveParamList = Lists.newArrayList();

        Map<String, List<TaxAgentManageRangePO>> allRangeMap = SalaryEntityUtil.group2Map(allManageRanges, k -> k.getTaxAgentId() + "-" + k.getRangeType());
        taxAgentIds.forEach(taxAgentId -> {
            // 当前个税扣缴义务人的所有范围
            List<TaxAgentManageRangePO> allRanges = Optional.ofNullable(allRangeMap.get(taxAgentId + "-" + TaxAgentRangeTypeEnum.TAXAGENT.getValue())).orElse(Collections.emptyList());
            List<DataCollectionEmployee> allSalaryEmployees = this.getManageRangeSalaryEmployees(taxAgentId, allRanges, salaryEmployees);
            taxAgentEmpSaveParamList.add(getTaxAgentEmpSyncParam(taxAgentId, allSalaryEmployees));

//            List<TaxAgentManageRangePO> allSubAdminRanges = Optional.ofNullable(allRangeMap.get(taxAgentId + "-" + TaxAgentRangeTypeEnum.SUBADMIN.getValue())).orElse(Collections.emptyList());
//            subAdminEmpSaveParamList.addAll(getTaxAgentSubAdminEmpSyncParam(taxAgentId, allSubAdminRanges, salaryEmployees));
        });
        Long employeeId = 0L;
        // 同步管理员的人员
        getTaxAgentEmpService(user).syncTaxAgentEmployee(taxAgentEmpSaveParamList, employeeId);
        // 同步分管理员的人员
//        taxAgentSubAdminEmployeeService.syncTaxAgentSubAdminEmployee(subAdminEmpSaveParamList, employeeId, tenantKey);

        //生成档案
        generateArchive();
    }

    /**
     * 获取个税扣缴义务人的同步参数
     *
     * @param taxAgentId
     * @param allSalaryEmployees
     * @return
     */
    private TaxAgentEmpSaveParam getTaxAgentEmpSyncParam(Long taxAgentId, List<DataCollectionEmployee> allSalaryEmployees) {
        return TaxAgentEmpSaveParam.builder().taxAgentId(taxAgentId).salaryEmployeeList(allSalaryEmployees).build();
    }

    /**
     * 获取分管理员的同步参数
     *
     * @param taxAgentId
     * @param allSubAdminRanges
     * @param salaryEmployees
     * @return
     */
    private List<TaxAgentSubAdminEmpSaveParam> getTaxAgentSubAdminEmpSyncParam(Long taxAgentId, List<TaxAgentManageRangePO> allSubAdminRanges, List<DataCollectionEmployee> salaryEmployees) {
        List<Long> allSubAdminIds = allSubAdminRanges.stream().map(TaxAgentManageRangePO::getTaxAgentSubAdminId).distinct().collect(Collectors.toList());
        List<TaxAgentSubAdminEmpSaveParam> subAdminEmpSaveParamList = Lists.newArrayList();
        allSubAdminIds.forEach(e -> {
            List<TaxAgentManageRangePO> singSubAdminRanges = allSubAdminRanges.stream().filter(r -> e.equals(r.getTaxAgentSubAdminId())).collect(Collectors.toList());
            List<DataCollectionEmployee> subAdminSalaryEmployees = this.getManageRangeSalaryEmployees(taxAgentId, singSubAdminRanges, salaryEmployees);

            subAdminEmpSaveParamList.add(TaxAgentSubAdminEmpSaveParam.builder().taxAgentId(taxAgentId).subAdminId(e).salaryEmployeeList(subAdminSalaryEmployees).build());
        });
        return subAdminEmpSaveParamList;
    }

    /**
     * 同步本地范围关联人员
     *
     * @param taxAgentId
     * @param allSalaryEmployees 个税扣缴义务人下的所有人员
     * @param employeeId
     */
    private void syncLocalEmpRange(Long taxAgentId, List<DataCollectionEmployee> allSalaryEmployees, Long employeeId) {
        log.info("同步个税扣缴人员范围");
        try {
            List<TaxAgentEmpSaveParam> taxAgentEmpSaveParamList = Collections.singletonList(getTaxAgentEmpSyncParam(taxAgentId, allSalaryEmployees));
            // 同步个税扣缴义务人的人员
            getTaxAgentEmpService(user).syncTaxAgentEmployee(taxAgentEmpSaveParamList, employeeId);

//        List<TaxAgentSubAdminEmpSaveParam> subAdminEmpSaveParamList = getTaxAgentSubAdminEmpSyncParam(taxAgentId, allSubAdminRanges);
            // 同步分管理员的人员
//        taxAgentSubAdminEmployeeService.syncTaxAgentSubAdminEmployee(subAdminEmpSaveParamList, employeeId);
        } catch (Exception e) {
            log.error("同步个税扣缴人员范围异常", e);
        }
    }


    /**
     * 同步人员范围
     *
     * @param taxAgentIds
     */
    @Override
    public void syncManageRange(List<Long> taxAgentIds, String index) {
        // 开始同步
        LocalRunnable localRunnable = new LocalRunnable() {
            @Override
            public void execute() {
                try {
                    Util_DataCache.setObjVal(index, "1");
                    handleSyncTaxAgentEmpData(taxAgentIds);
                } finally {
                    Util_DataCache.clearVal(index);
                }
            }
        };
        ThreadPoolUtil.execute(localRunnable);
    }

    /**
     * 导入数据
     *
     * @param taxAgentImportParam
     * @return
     */
    @Override
    public Map<String, Object> importData(TaxAgentImportParam taxAgentImportParam) {
        Boolean openDevolution = getTaxAgentService(user).isOpenDevolution();
        long currentEmployeeId = user.getUID();
        Map<String, Object> apidatas = new HashMap<String, Object>();

        //查询对于人员信息导入筛选的全局配置
        SalarySysConfPO salarySysConfPO = getSalarySysConfMapper().getOneByCode("matchEmployeeMode");
        String confValue = (salarySysConfPO != null && salarySysConfPO.getConfValue() != null && !"".equals(salarySysConfPO.getConfValue())) ? salarySysConfPO.getConfValue() : "0";

        //检验参数
        checkImportParam(taxAgentImportParam);

        //excel文件id
        String imageId = Util.null2String(taxAgentImportParam.getImageId());
        Validate.notBlank(imageId, "imageId为空");
        //个税扣缴义务人
        Long taxAgentId = taxAgentImportParam.getTaxAgentId();
        TaxAgentPO taxAgent = getTaxAgentService(user).getById(taxAgentId);
        InputStream fileInputStream = null;
        try {
            fileInputStream = ImageFileManager.getInputStreamById(Integer.parseInt(imageId));
            List<TaxAgentManageRangeEmployeeListDTO> rangeEmployees = ExcelParseHelper.parse2Map(fileInputStream, TaxAgentManageRangeEmployeeListDTO.class, 0, 1, 6, "TaxAgentEmployee.xlsx");

            int total = rangeEmployees.size();
            int index = 0;
            int successCount = 0;
            int errorCount = 0;

            //人员信息
            List<DataCollectionEmployee> employees = getSalaryEmployeeService().listEmployee();

            // 错误excel内容
            List<Map> errorData = new ArrayList<>();
            //合规数据
            List<TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam> eligibleData = new ArrayList<>();
            // 全部员工状态
            Set<String> allEmployeeStatuses = new HashSet<>();
            allEmployeeStatuses.addAll(SalaryEmployeeStatusEnum.getAllSalaryEmployeeStatusValues());

            TaxAgentRangeSaveParam taxAgentRangeSaveParam = new TaxAgentRangeSaveParam();
            taxAgentRangeSaveParam.setTaxAgentId(taxAgentId);
            taxAgentRangeSaveParam.setIncludeType(1);
            taxAgentRangeSaveParam.setSync(true);
//            taxAgentRangeSaveParam.setEmployeeStatus(allEmployeeStatuses);

            for (int i = 0; i < rangeEmployees.size(); i++) {
                TaxAgentManageRangeEmployeeListDTO dto = rangeEmployees.get(i);
                //待插入数据库对象
                TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam po = new TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam();
                po.setTargetType(TargetTypeEnum.EMPLOYEE);

                //异常点数量
                int errorSum = 0;

                //行号
                String rowIndex = String.format("第%s行", i + 2);

                //相同的姓名
                String userName = dto.getUsername();
                String deparmentName = dto.getDepartmentName();
                String mobile = dto.getMobile();
                String workcode = dto.getJobNum();
                String idNo = dto.getIdNo();

                String employeeStatusStr = dto.getEmployeeStatus();
                List<Long> employeeSameIds = new ArrayList<>();

                //筛选导入人员信息可以在人力资源池中匹配到的人员信息
                List<DataCollectionEmployee> emps = getSalaryEmployeeService().matchImportEmployee(confValue, employees, userName, deparmentName, mobile, workcode, idNo, null);
                if (CollectionUtils.isNotEmpty(emps)) {
                    employeeSameIds = emps.stream().map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList());
                }

                //含在职和离职，选在职数据
                if (CollectionUtils.isNotEmpty(emps) && emps.size() > 1) {
                    employeeSameIds = emps.stream().filter(e -> UserStatusEnum.getNormalStatus().contains(e.getStatus())).map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList());
                }
                if (CollectionUtils.isNotEmpty(emps) && emps.size() == 1) {
                    employeeSameIds = emps.stream().map(DataCollectionEmployee::getEmployeeId).collect(Collectors.toList());
                }

                //当人员信息导入筛选的全局配置为"0"时，姓名才是必填项
                if (StringUtils.isBlank(userName) && "0".equals(confValue)) {
                    //姓名 不能为空
                    //错误消息对象
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + "姓名不能为空");
                    errorData.add(errorMessageMap);
                    errorSum += 1;
                } else if (CollectionUtils.isEmpty(employeeSameIds) || employeeSameIds.size() > 1) {
                    Map<String, String> errorMessageMap = Maps.newHashMap();
                    errorMessageMap.put("message", rowIndex + "员工信息不存在或者存在多个员工");
                    errorData.add(errorMessageMap);
                    errorSum += 1;
                } else {
                    Long employeeId = CollectionUtils.isNotEmpty(employeeSameIds) && employeeSameIds.size() == 1 ? employeeSameIds.get(0) : null;
                    if (employeeId != null && employeeId > 0) {
                        po.setTargetId(employeeId);
                    } else {
                        //姓名错误，系统内不存在该姓名
                        Map<String, String> errorMessageMap = new HashMap<>();
                        errorMessageMap.put("message", rowIndex + "姓名错误，系统内不存在该姓名");
                        errorData.add(errorMessageMap);
                        errorSum += 1;
                    }
                }

                // 设置员工状态
                if (StringUtils.isEmpty(employeeStatusStr)) {
                    po.setEmployeeStatus(allEmployeeStatuses);
                } else {
                    Boolean[] haveError = {false};
                    // 人员状态字符串转换为对应的value
                    List<String> status = SalaryEmployeeStatusEnum.parseByFormatStr(employeeStatusStr, haveError);
                    if (haveError[0]) {
                        Map<String, String> errorMessageMap = new HashMap<>();
                        errorMessageMap.put("message", rowIndex + "员工状态不存在，或格式有误。格式为：试用、正式、临时、试用延期");
                        errorData.add(errorMessageMap);
                        errorSum += 1;
                    } else {
                        po.setEmployeeStatus(status);
                    }
                }


                if (Objects.isNull(taxAgent)) {
                    //个税扣缴义务人不存在
                    Map<String, String> errorMessageMap = new HashMap<>();
                    errorMessageMap.put("message", "个税扣缴义务人不存在或不在权限范围内");
                    errorData.add(errorMessageMap);
                    errorSum += 1;
                }

                //fixme 分权判断
                if (errorSum == 0) {
                    successCount += 1;
                    // 合格数据
                    eligibleData.add(po);
                } else {
                    errorCount += 1;
                    // 添加错误数据
                }
            }

            //入库-----------------start
            eligibleData = handleImportData(eligibleData);
            taxAgentRangeSaveParam.setTargetParams(eligibleData);
            // 查询已有的管理范围
            List<TaxAgentManageRangePO> taxAgentManageAllRanges = listByTaxAgentId(taxAgentId);
            List<TaxAgentManageRangePO> taxAgentManageRanges = taxAgentManageAllRanges.stream().filter(f -> f.getIncludeType().equals(taxAgentRangeSaveParam.getIncludeType())).collect(Collectors.toList());
            List<TaxAgentManageRangePO> oldManageList = new ArrayList<>();
            taxAgentManageRanges.stream().forEach(p -> {
                TaxAgentManageRangePO target = new TaxAgentManageRangePO();
                BeanUtils.copyProperties(p, target);
                oldManageList.add(target);
            });

            // 处理一下本次的保存参数（如果原来添加过对应的人员（/部门/岗位），那么本次不需要新增，只需要更新）
            TaxAgentBO.Result result = TaxAgentBO.handleTaxAgentRange(taxAgentManageRanges, taxAgentRangeSaveParam, taxAgent.getId(), (long) user.getUID(), true);

            /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================start */
            List<TaxAgentManageRangePO> allRanges = Lists.newArrayList(taxAgentManageAllRanges);
            allRanges.addAll(result.getNeedInsertTaxAgentManageRanges());
            allRanges.addAll(result.getNeedUpdateTaxAgentManageRanges());
            // 去重
            allRanges = allRanges.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getTaxAgentId() + "." + f.getRangeType() + "." + f.getTargetType() + "." + f.getTargetId() + "." + f.getEmployeeStatus() + "." + f.getIncludeType()))), ArrayList::new));

            List<DataCollectionEmployee> salaryEmployees = getSalaryEmployeeService().listAll(UseEmployeeTypeEnum.ALL);
            List<DataCollectionEmployee> allSalaryEmployees = this.getManageRangeSalaryEmployees(taxAgentId, allRanges, salaryEmployees);

            /* 检查当前个税扣缴义务人的所有人员范围与所有分管理员的管理范围===========================end */
            if (CollectionUtils.isNotEmpty(result.getNeedInsertTaxAgentManageRanges())) {
                result.getNeedInsertTaxAgentManageRanges().forEach(range -> {
                    getTaxAgentManageRangeMapper().insertIgnoreNull(range);
                    // 记录操作日志
                    String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                    SalaryLoggerUtil.recordAddSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "新增人员范围"), SalaryI18nUtil.getI18nLabel(0, "新增人员范围") + name, range, user);
                });
            }
            if (CollectionUtils.isNotEmpty(result.getNeedUpdateTaxAgentManageRanges())) {
                Map<Long, TaxAgentManageRangePO> oldMap = SalaryEntityUtil.convert2Map(oldManageList, TaxAgentManageRangePO::getId);
                result.getNeedUpdateTaxAgentManageRanges().forEach(range -> {
                    getTaxAgentManageRangeMapper().updateIgnoreNull(range);
                    // 记录操作日志
                    TaxAgentManageRangePO oldPO = oldMap.getOrDefault(range.getId(), TaxAgentManageRangePO.builder().build());
                    String name = taxAgent.getName() + "_" + TargetTypeEnum.parseByValue(range.getTargetType()).getDefaultLabel() + "_" + range.getTargetId();
                    SalaryLoggerUtil.recordUpdateSingleLog(SalaryElogConfig.taxAgentLoggerTemplate, range.getTaxAgentId(), name, SalaryI18nUtil.getI18nLabel(0, "更新人员范围"), SalaryI18nUtil.getI18nLabel(0, "更新人员范围") + name, oldPO, range, user);
                });

            }

            /* 同步本地人员范围的关联人员=========================== */
            syncLocalEmp(taxAgentId, allSalaryEmployees, taxAgentRangeSaveParam.isSync());
            //-----------------end

            apidatas.put("successCount", successCount);
            apidatas.put("errorCount", errorCount);
            apidatas.put("errorData", errorData);

        } finally {
            IOUtils.closeQuietly(fileInputStream);
        }
        return apidatas;
    }

    // 处理导入数据
    private List<TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam> handleImportData(List<TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam> pos) {
        if (CollectionUtils.isEmpty(pos)) {
            return Collections.emptyList();
        }
        // 多条相同人的则以第一条为准，如果逆序排列（用于重复的则以最后一条为准）Collections.reverse(pos);
        // 去重（通过记录的唯一条件(人员id）
        List<TaxAgentManageRangeSaveParam.TaxAgentSubAdminRangeTargetParam> finalPos = pos.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(f -> f.getTargetId()))), ArrayList::new));
        return finalPos;
    }

    private void checkImportParam(TaxAgentImportParam importParam) {
        //excel文件id
        String imageId = Util.null2String(importParam.getImageId());

        if (StringUtils.isBlank(imageId)) {
            throw new SalaryRunTimeException("文件不存在");
        }
        Long taxAgentId = importParam.getTaxAgentId();
        if (Objects.isNull(taxAgentId)) {
            throw new SalaryRunTimeException("个税扣缴义务人为空");
        }
    }

}
